1 Podsumowanie

Zastosowany regresor random forest wykazuje wystarczająco dobre wyniki (w oparciu o RMSE oraz R²), by stwierdzić, że możliwe jest przewidywanie długości śledzi w oparciu o dane zawarte w zbiorze.
Z uzyskanych wyników można wysunąć wniosek, że najważniejsze powody zmniejszania się średniej długości śledzi oceanicznych to zmiana temperatury przy powierzchni wody, natężenie połowów oraz roczny narybek.
Z drugiej strony nie można jednoznacznie stwierdzić, że te wyniki są poprawne. Różne modele regresji mają w zwyczaju wskazywać różne atrybuty jako najważniejsze, więc przy zastosowaniu innego modelu może się okazać, że wyniki są znacząco różne od uzyskanych.

2 Wykorzystane biblioteki

Biblioteki wykorzystane w tym projekcie służą przede wszystkim do działania na zbiorze danych (np. dplyr, tidyr), wyświetlania danych (knitr) i wykresów (np. ggplot2, plotly) oraz do wykonywania regresji (caret).
Dodatkowo w tej sekcji znajduje się kod zapewniający powtarzalność wyników.

names(sessionInfo()$other) %>%
kable(col.names=NULL)
caret
plotly
ggcorrplot
knitr
dplyr
tidyr
Hmisc
ggplot2
Formula
survival
lattice
set.seed(42)

3 Opis danych

Zbiór używany do analizy został pobrany ze strony przedmiotu. Zawiera on dane z ostatnich 60 lat dotyczące rozmiarów śledzi oraz warunków, w jakich żyją.

Zgodnie z opisem ze strony przedmiotu, Kolejne kolumny w zbiorze danych to:

  • length: długość złowionego śledzia [cm];
  • cfin1: dostępność planktonu [zagęszczenie Calanus finmarchicus gat. 1];
  • cfin2: dostępność planktonu [zagęszczenie Calanus finmarchicus gat. 2];
  • chel1: dostępność planktonu [zagęszczenie Calanus helgolandicus gat. 1];
  • chel2: dostępność planktonu [zagęszczenie Calanus helgolandicus gat. 2];
  • lcop1: dostępność planktonu [zagęszczenie widłonogów gat. 1];
  • lcop2: dostępność planktonu [zagęszczenie widłonogów gat. 2];
  • fbar: natężenie połowów w regionie [ułamek pozostawionego narybku];
  • recr: roczny narybek [liczba śledzi];
  • cumf: łączne roczne natężenie połowów w regionie [ułamek pozostawionego narybku];
  • totaln: łączna liczba ryb złowionych w ramach połowu [liczba śledzi];
  • sst: temperatura przy powierzchni wody [°C];
  • sal: poziom zasolenia wody [Knudsen ppt];
  • xmonth: miesiąc połowu [numer miesiąca];
  • nao: oscylacja północnoatlantycka [mb].

Zbiór danych wczytano z pliku znajdującego się na dysku i zapisano w zmiennej ‘herrings’.

classes <- c('integer', 'numeric', 'numeric', 'numeric', 'numeric', 'numeric', 'numeric', 'numeric', 'numeric', 'integer', 'numeric', 'numeric', 'numeric', 'numeric', 'integer', 'numeric')
herrings <- as_tibble(read.csv(paste(getwd(), "sledzie.csv", sep='/'), colClasses = classes, na.strings="?"))

4 Wartości puste

Wartości puste zostały zastąpione wartościami poprzednimi, lub, jeśli to niemożliwe, następnymi.

herrings <- fill(herrings, everything(), .direction='downup')

5 Analiza zbioru danych

Poniżej wyświetlono podstawowe informacje o danych oraz ich próbkę:

## [1] "Liczba kolumn: 16"
## [1] "Liczba wierszy: 52582"
X length cfin1 cfin2 chel1 chel2 lcop1 lcop2 fbar recr cumf totaln sst sal xmonth nao
0 23.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
1 22.5 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
2 25.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
3 25.5 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
4 24.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
5 22.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
6 24.0 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8
7 23.5 0.02778 0.27785 2.46875 21.43548 2.54787 26.35881 0.356 482831 0.3059879 267380.8 14.30693 35.51234 7 2.8

Poniżej znajduje się tabela zawierająca informacje o wartości minimalnej, maksymalnej, średniej oraz odchyleniu standardowym danych z każdej kolumny.

Min, max, średnia i odchylenie standardowe wartości w każdej kolumnie (poza liczbą porządkową i miesiącem połowu)
xfunction length cfin1 cfin2 chel1 chel2 lcop1 lcop2 fbar recr cumf totaln sst sal nao
min 19.000 0.000 0.000 0.000 5.238 0.307 7.849 0.068 140515.0 0.068 144136.7 12.769 35.398 -4.890
max 32.500 37.667 19.396 75.000 57.706 115.583 68.736 0.849 1565890.0 0.398 1015594.9 14.729 35.612 5.080
mean 25.304 0.446 2.025 10.004 21.218 12.803 28.423 0.330 520366.5 0.230 514972.9 13.875 35.510 -0.092
sd 1.653 0.957 3.709 14.293 9.979 15.049 13.849 0.160 271062.9 0.092 221382.1 0.437 0.037 2.246

6 Analiza wartości atrybutów

Przedstawiono w formie tabeli jak liczne są dane przedziały wartości w każdej kolumnie.

Rozkład wartości w danych wejściowych
length length_n cfin1 cfin1_n cfin2 cfin2_n chel1 chel1_n chel2 chel2_n lcop1 lcop1_n lcop2 lcop2_n fbar fbar_n
(-Inf,20] 36 (-Inf,0.1] 24105 (-Inf,0.5] 20574 (-Inf,6] 26466 (-Inf,8] 4936 (-Inf,5] 18251 (-Inf,10] 4934 (-Inf,0.1] 3525
(20,22] 1782 (0.1,0.2] 9539 (0.5,1] 12721 (6,12] 16022 (8,16] 14389 (5,10] 13070 (10,20] 8732 (0.1,0.2] 8591
(22,24] 12058 (0.2,0.5] 8484 (1,2] 7751 (12,18] 3082 (16,24] 10775 (10,20] 7333 (20,30] 18082 (0.2,0.3] 11529
(24,26] 23101 (0.5,2] 6351 (2,5] 7063 (18,24] 2062 (24,32] 14884 (20,40] 11426 (30,40] 12171 (0.3,0.4] 12121
(26,28] 14029 (2,4] 3292 (5,10] 2076 (30,36] 2442 (32,40] 7087 (40,60] 805 (40,50] 5759 (0.4,0.5] 8392
(28,30] 1526 (4,30] 805 (10,18] 888 (36,42] 804 (40,48] 6 (60,80] 1691 (50,60] 6 (0.5,0.6] 7045
(30, Inf] 50 (30, Inf] 6 (18, Inf] 1509 (62, Inf] 1704 (56, Inf] 505 (100, Inf] 6 (60, Inf] 2898 (0.6, Inf] 1379
Rozkład wartości w danych wejściowych
recr recr_n cumf cumf_n totaln totaln_n sst sst_n sal sal_n xmonth xmonth_n nao nao_n
(-Inf,3e+05] 9924 (-Inf,0.1] 4223 (-Inf,2e+05] 5704 (-Inf,13] 877 (-Inf,35.4] 2165 (-Inf,3] 6744 (-Inf,-4] 1579
(3e+05,5e+05] 23154 (0.1,0.14] 6062 (2e+05,3e+05] 5908 (13,13.3] 4633 (35.4,35.44] 1333 (3,5] 6434 (-4,-2.5] 7059
(5e+05,7e+05] 5471 (0.14,0.18] 6270 (3e+05,4e+05] 7651 (13.3,13.5] 2688 (35.44,35.48] 4339 (5,6] 4218 (-2.5,-1.1] 10753
(7e+05,9e+05] 9545 (0.18,0.23] 8240 (4e+05,5e+05] 4005 (13.5,13.7] 14579 (35.48,35.5] 2322 (6,7] 6922 (-1.1,0] 5748
(9e+05,1.1e+06] 2221 (0.23,0.28] 12519 (5e+05,6e+05] 11169 (13.7,13.9] 6658 (35.5,35.52] 28444 (7,8] 9920 (0,1.1] 10361
(1.1e+06,1.3e+06] 878 (0.28,0.32] 6127 (6e+05,7e+05] 4144 (13.9,14.2] 10050 (35.52,35.56] 11355 (8,9] 5714 (1.1,2.5] 9317
(1.3e+06,1.5e+06] 1383 (0.32,0.36] 3377 (7e+05,8e+05] 10415 (14.2,14.5] 8463 (35.56,35.6] 914 (9,10] 7972 (2.5,4] 7328
(1.5e+06, Inf] 6 (0.36, Inf] 5764 (8e+05, Inf] 3586 (14.5, Inf] 4634 (35.6, Inf] 1710 (10, Inf] 4658 (4, Inf] 437

7 Korelacja między zmiennymi

Zbadano korelację między zmiennymi i wyświetlono ją w postaci macierzy korelacji, gdzie intensywniejszy kolor oznacza większą korelację, czerwony negatywną a zielony pozytywną.

herrings_cor <- herrings %>%
  select(-X) %>% 
  as.matrix() %>%
  rcorr(type = 'spearman')
correlation <- round(herrings_cor$r, 2)

ggcorrplot(correlation, hc.order = TRUE, 
           type = 'upper', 
           lab = TRUE, 
           lab_size = 3, 
           method='circle',
           title='Korelacja między zmiennymi',
           colors=c('red', 'white', 'green'),
           ggtheme=theme_bw)

8 Wykres przedstawiający zmianę rozmiaru śledzia w czasie

Utworzono interaktywny wykres prezentujący zmianę rozmiaru śledzia w czasie na podstawie losowo wybranych 150 wartości.

9 Regresja

W tej sekcji przygotowane zostały 2 modele regresora, których zadaniem jest przewidywanie rozmiaru śledzia w oparciu o pozostałe dane w zbiorze (atrybuty). W oparciu o korelację atrybutów z długością śledzi zostało wybrane 7 o największej (najdalszej od zera, ujemnej bądź dodatniej) korelacji.

9.1 Przygotowanie danych

Zbiór danych został podzielony na 3 zbiory: uczący, testowy i walidujący. Zbiory uczący i testowy zostały wykorzystane do zmian parametrów modeli oraz wybrania najskuteczniejszego. Zbiór walidujący został użyty jako ostateczny test końcowo wybranego modelu.

splitIndex <- createDataPartition(herrings$length, p = 0.8, list = FALSE)
splitIndex2 <- createDataPartition(herrings$length, p = 0.9, list = FALSE)
trainData <- herrings[splitIndex, ]
testData <- herrings[setdiff(splitIndex2, splitIndex), ]
validData <- herrings[-splitIndex2, ]

9.2 Regresja liniowa

Prostszym z testowanych modeli jest regresja liniowa. Model został utworzony tak jak jest to widoczne w poniższym fragmencie kodu.

model <- train(length ~ cumf+fbar+nao+recr+chel2+lcop2+sst+lcop1,
               data = trainData,
               method = "lm")

predictions <- predict(model, testData)
performance <- postResample(predictions, testData$length)

Następnie została zbadana skuteczność modelu. W formie wykresu przedstawiono jakie długości (uśrednione) przewidywał model dla danych realnych długości.

##      RMSE  Rsquared       MAE 
## 1.3671122 0.3139105 1.0877829

9.3 Regresja random forest

Drugim testowanym modelem jest model random forest zawierający 15 drzew. Model został utworzony tak jak jest to widoczne na poniższym fragmencie kodu.

model <- train(length ~ cumf+fbar+nao+recr+chel2+lcop2+sst,
               data = trainData,
               method = "rf",
               tuneLength=15,
               ntree=15)
## note: only 6 unique complexity parameters in default grid. Truncating the grid to 6 .
predictions <- predict(model, testData)
performance <- postResample(predictions, testData$length)

Efektywność modelu zbadana na zbiorze testowym wygląda następująco:

##      RMSE  Rsquared       MAE 
## 1.1887982 0.4811895 0.9429176

Następnie została zbadana skuteczność modelu. W formie wykresu przedstawiono jakie długości (uśrednione) przewidywał model dla danych realnych długości.

##      RMSE  Rsquared       MAE 
## 1.1904083 0.4729910 0.9453545

9.4 Analiza ważności atrybutów

Model oparty o random forest okazał się być skuteczniejszy. Wyświetlono ważność atrybutów, jaka została dzięki niemu odkryta.

print(varImp(model))
## rf variable importance
## 
##       Overall
## sst   100.000
## fbar   46.242
## recr   40.903
## nao    20.898
## cumf   14.246
## chel2   9.966
## lcop2   0.000

W oparciu o uzyskane dane można stwierdzić, że najważniejszym powodem zmniejszania się długości śledzi oceanicznych jest zmiana temperatury przy powierzchni wody. Biorąc pod uwagę zbadaną wcześniej korelację można stwierdzić, że niższe temperatury negatywnie wpływają na rozmiary śledzi. Inne istotne atrybuty to ułamek pozostawionego narybku przy połowach oraz roczny narybek.